/*
 * test.cpp
 *
 *  Created on: 31-Oct-2011
 *      Author: willion
 */

#include "row.h"
#include "block.h"

#include <iostream>
using namespace std;

#include <cstdlib>

#include <getopt.h>
#include <string.h>

#include <errno.h>

int main(int argc, char** argv)
{
	int seed_flag = 0;

	int size = 3;
	int loop = 5;
	int proc = 2;
	int seed = 0;
	int par = ROW;
	int mode = 0;

	struct option long_options[] =
	{
			//set a flag, allows user-specific seed
			{"seed", required_argument, &seed_flag, 1},
			//the size of matrix
			{"size", required_argument, 0, 's'},
			//loop times
			{"loop", required_argument, 0, 'l'},
			//partition method
			{"par", required_argument, 0, 'p'},
			{0, 0, 0, 0}
	};

	int option_index = 0;

	int multi_method = BASE_IMP;

	char c = '\0';

	while ((c = getopt_long(argc, argv, "r:s:l:p:m:", long_options, &option_index)) != -1)
	{
		switch(c)
		{
			//user-specific seed
			case 0:
			{

			}
			case 'r':
			{
				if (seed_flag == 1)
				{
					seed = atoi(optarg);
				}

				break;
			}
			//user-specific matrix size
			case 's':
			{
				size = atoi(optarg);

				break;
			}
			//user-specific loop time
			case 'l':
			{
				loop = atoi(optarg);

				break;
			}
			//partition method
			case 'p':
			{
				if (strcmp(optarg, "row") == 0 )
				{
					par = ROW;
				}
				else if (strcmp(optarg, "block") == 0 )
				{
					par = BLOCK;
				}

				break;
			}
			case 'm':
			{
				if (strcmp(optarg, "naive") == 0 )
				{
					multi_method = BASE_IMP;
				}
				else if (strcmp(optarg, "adv") == 0 )
				{
					multi_method = ADV_IMP;
				}

				break;
			}
			default:
			{
				break;
			}
		}
	}

	//partition method
	baseOP* ob = NULL;
	switch(par)
	{
		case NAIVE:
		{
			ob = new row(size, size, size, loop);

			break;
		}
		case BLOCK:
		{
			ob = new block(size, size, size, loop);

			break;
		}
		default:
		{
			ob = new row(size, size, size, loop);

			break;
		}
	}

	ob->go(multi_method);

	//ob->display_matrix(baseOP::LEFT);
	//ob->display_matrix(baseOP::RIGHT);
	//ob->display_matrix(baseOP::RESULT);

	delete ob;
	ob = NULL;

	return EXIT_SUCCESS;
}
